package xyz.zhno.single;

/**
 * 单例模式（DCL）: 饿汉式,双重检测锁，线程安全
 * @author zh_o
 * @date 2020-11-11
 */
public class LazySingleTwo {

    /**
     * 创建实例
     */
    private volatile static LazySingleTwo lazySingleTwo;

    /**
     * 私有化构造方法
     */
    private LazySingleTwo() {}

    /**
     * 提供公共方法返回实例
     */
    public static LazySingleTwo getInstance() {
        if (lazySingleTwo == null) {
            synchronized (LazySingleTwo.class) {
                if (lazySingleTwo == null) {
                    /*
                     * new 不是一个原子性操作
                     * 1. 分配内存空间
                     * 2. 执行构造方法，初始化对象
                     * 3. 把对象指向分配的内存空间
                     * 编译时可能进行指令重排，不是按照以上的顺序执行，极端情况下可能出现线程不安全问题
                     * 因此需要在实例加上关键字 volatile 防止指令重排
                     */
                    lazySingleTwo = new LazySingleTwo();
                }
            }
        }
        return lazySingleTwo;
    }
}
